Public Class DataGridViewLookUpComboBoxColumn
    Inherits DataGridViewColumn

    Private _LookUpList As LookUpList

    Public Sub New()
        Me.New(New LookUpList)
    End Sub

    Public Sub New(ByVal LookUpList As LookUpList)
        MyBase.New(New DataGridViewLookUpComboBoxCell())
        _LookUpList = LookUpList
    End Sub

    Public Property LookupList() As LookUpList
        Get
            Return _LookUpList
        End Get
        Set(ByVal value As LookUpList)
            _LookUpList = value
        End Set
    End Property

End Class






Public Class LookUpList
    Inherits List(Of Core.IMetisCommonEntity)


    Private _IDlist As New System.Collections.Generic.Dictionary(Of Integer, Integer)


    Public Overloads Sub Clear()
        _IDlist.Clear()
        Me.Clear()
    End Sub

    Public Overloads Function ContainsID(ByVal value As Integer) As Boolean
        Return _IDlist.ContainsKey(value)
    End Function

    Public Overloads Function IndexOfID(ByVal value As Integer) As Integer
        If _IDlist.ContainsKey(value) Then
            Return _IDlist(value)
        Else
            Return -1
        End If
    End Function

    Public Overloads Function ContainsValue(ByVal value As String) As Boolean
        Return Me.IndexOfValue(value) >= 0
    End Function

    Public Overloads Function IndexOfValue(ByVal value As String) As Integer
        Dim FirstIndex As Integer = 0
        Dim LastIndex As Integer = Me.Count
        Dim MidIndex As Integer

        Do While FirstIndex < LastIndex
            MidIndex = FirstIndex + CInt(Math.Truncate((LastIndex - FirstIndex) / 2))

            If String.Compare(Me(MidIndex).Name, value, True) < 0 Then
                FirstIndex = MidIndex + 1
            Else
                LastIndex = MidIndex
            End If
        Loop

        If ((FirstIndex < Me.Count) AndAlso (Me(FirstIndex).Name.Equals(value, StringComparison.OrdinalIgnoreCase))) Then
            Return FirstIndex
        Else
            Return -1
        End If

    End Function

    Function ValueByID(ByVal id As Integer) As String
        Return Me(_IDlist(id)).Name
    End Function

    Function IDbyValue(ByVal value As String) As Integer
        Dim tmpIndex As Integer = IndexOfValue(value)
        If tmpIndex >= 0 Then
            Return Me(tmpIndex).ID
        Else
            Return -1
        End If
    End Function


    Public Overloads Function Remove(ByVal value As Core.IMetisCommonEntity) As Boolean
        Dim index As Integer = Me.IndexOfValue(value.Name)
        If index >= 0 Then
            _IDlist.Remove(Me(index).ID)
            Me.RemoveAt(index)
            Return False
        Else
            Return False
        End If
    End Function


    Public Overloads Sub RemoveAt(ByVal index As Integer)
        _IDlist.Remove(Me(index).ID)
        MyBase.RemoveAt(index)
    End Sub


    Public Overloads Sub Add(ByVal item As Core.IMetisCommonEntity)
        Dim FirstIndex As Integer = 0
        Dim LastIndex As Integer = Me.Count
        Dim MidIndex As Integer = 0


        Do While FirstIndex < LastIndex
            MidIndex = FirstIndex + CInt(Math.Truncate((LastIndex - FirstIndex) / 2))

            If Me(MidIndex).CompareTo(item) < 0 Then
                FirstIndex = MidIndex + 1
            Else
                LastIndex = MidIndex
            End If
        Loop


        If LastIndex >= Me.Count Then
            MyBase.Add(item)
            _IDlist.Add(item.ID, LastIndex)
        Else
            MyBase.Insert(LastIndex, item)
            _IDlist.Add(item.ID, LastIndex)
            For i As Integer = LastIndex To Me.Count - 1
                _IDlist(Me(i).ID) = i
            Next
        End If
    End Sub

    Public Overloads Sub Insert(ByVal index As Integer, ByVal item As Core.IMetisCommonEntity)
        Me.Add(item)
    End Sub

End Class
